package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.exception.StgyException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.web.admin.dto.ApartmentInfoSearchDto;
import com.atguigu.lease.web.admin.dto.ApartmentInfoSubmitDto;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.ApartmentInfoService;
import com.atguigu.lease.web.admin.service.ApartmentLabelService;
import com.atguigu.lease.web.admin.vo.ApartmentDetailVo;
import com.atguigu.lease.web.admin.vo.ApartmentInfoVo;
import com.atguigu.lease.web.admin.vo.FeeValueVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author 1
* @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
* @createDate 2024-08-28 11:00:25
*/
@Service
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
    implements ApartmentInfoService {
    @Resource
    ApartmentFacilityMapper apartmentFacilityMapper;
    @Resource
    ApartmentLabelMapper apartmentLabelMapper;
    @Resource
    ApartmentLabelService apartmentLabelService;



    @Resource
    ApartmentFeeValueMapper apartmentFeeValueMapper;
    @Resource
    GraphInfoMapper graphInfoMapper;
    @Resource
    DistrictInfoMapper districtInfoMapper;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateApartmentInfo(ApartmentInfoSubmitDto submitDto) {
        //1、唯一校验
        Long id = submitDto.getId()==null?-1L:submitDto.getId();
        ApartmentInfo dbApartmentInfo = this.getOne(Wrappers.lambdaQuery(ApartmentInfo.class)
                .eq(ApartmentInfo::getDistrictId, submitDto.getDistrictId())
                .eq(ApartmentInfo::getName, submitDto.getName())
                .last("limit 1"));
        if(dbApartmentInfo!=null && !id.equals(dbApartmentInfo.getId())){
            throw new StgyException(ResultCodeEnum.DATA_EXISTS_ERROR);
        }
        //2、判断新增还是更新
        //更新时：删除公寓的其他的映射数据
        if(!id.equals(-1L)){
            //更新：先删除 缓存的映射数据
            //多对多映射的数据  可以使用物理删除，没有存储真实数据
            //apartment_facility: 公寓id映射配套id    根据公寓id删除它的所有配套
            apartmentFacilityMapper.deleteByApartmentInfoId(id);
            //aparment_label
            apartmentLabelMapper.deleteByApartmentInfoId(id);
            //aparment_fee_value
            apartmentFeeValueMapper.deleteByApartmentInfoId(id);
            //graph_info:
            graphInfoMapper.deleteByApartmentInfoId(id);
        }

        //3、保存或更新公寓信息
        ApartmentInfo apartmentInfo = new ApartmentInfo();
        BeanUtils.copyProperties(submitDto , apartmentInfo);
        //查询公寓的省市区名称设置
        // dName->区   cName->市   pName->省
        Map<String,String> namesMap = districtInfoMapper.selectNamesByDid(submitDto.getDistrictId());
        apartmentInfo.setDistrictName(namesMap.get("dName"));
        apartmentInfo.setCityName(namesMap.get("cName"));
        apartmentInfo.setProvinceName(namesMap.get("pName"));
        this.saveOrUpdate(apartmentInfo);
        //4、保存公寓的映射数据
        //apartment_facility:  4    21  22  23
        // 配套id集合  insert into apartment_facitily(apartment_id , facility_id) values(4 , 21),(4,22);
        //重新获取id: 为了获取新增后的id
        id = apartmentInfo.getId();
        List<Long> facilityInfoIds = submitDto.getFacilityInfoIds();
        if(!CollectionUtils.isEmpty(facilityInfoIds)){
            // 使用对象新增/更新才会触发自动填充
            apartmentFacilityMapper.insertBatch(id ,facilityInfoIds );//自定义sql：
        }

        //aparment_label
        if(!CollectionUtils.isEmpty(submitDto.getLabelIds())){
            Long finalId = id;
            List<ApartmentLabel> apartmentLabels = submitDto.getLabelIds().stream().map(labelId -> {
                ApartmentLabel apartmentLabel = new ApartmentLabel();
                apartmentLabel.setApartmentId(finalId);
                apartmentLabel.setLabelId(labelId);
                return apartmentLabel;
            }).collect(Collectors.toList());
            apartmentLabelService.saveBatch(apartmentLabels);
        }
        //aparment_fee_value
        List<Long> feeValueIds = submitDto.getFeeValueIds();
        if(!CollectionUtils.isEmpty(feeValueIds)){
            //
            apartmentFeeValueMapper.insertBatch(id ,feeValueIds );//自定义sql：
        }
        //graph_info
        if(!CollectionUtils.isEmpty(submitDto.getGraphVoList())){
            for (GraphInfo graphInfo : submitDto.getGraphVoList()) {
                graphInfo.setItemType(1);
                graphInfo.setItemId(id);
            }
            graphInfoMapper.insertBatch(submitDto.getGraphVoList());
        }
        return true;
    }

    @Override
    public Page<ApartmentInfoVo> pageItem(ApartmentInfoSearchDto searchDto) {
        //封装分页数据
        Page<ApartmentInfoVo> page = new Page<>(searchDto.getCurrent(), searchDto.getSize());
        //使用mp支持的分页对象 自定义sql
        List<ApartmentInfoVo> apartmentInfoVos = baseMapper.selectPageItem(page , searchDto);

        //组装分页数据
        page.setRecords(apartmentInfoVos);
        return page;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeApartmetInfoById(Long id) {
        this.removeById(id);
        apartmentFacilityMapper.deleteByApartmentInfoId(id);
        //aparment_label
        apartmentLabelMapper.deleteByApartmentInfoId(id);
        //aparment_fee_value
        apartmentFeeValueMapper.deleteByApartmentInfoId(id);
        //graph_info:
        graphInfoMapper.deleteByApartmentInfoId(id);
        return true;
    }

    @Override
    public ApartmentDetailVo getDetailById(Long id) {
        //多步查询组装数据
        ApartmentInfo apartmentInfo = this.getById(id);
        if(apartmentInfo==null){
            throw new StgyException(ResultCodeEnum.DATA_ERROR);
        }
        //label_info
        List<LabelInfo>labelInfoList = apartmentLabelMapper.selectLabelInfosByApartmentId(id);
        //facility_info 公寓配套
        List<FacilityInfo> facilityInfoList = apartmentFacilityMapper.selectFacilityInfosByApartmentId(id);
        //fee_value  杂费和键
        List<FeeValueVo> feeValueVoList = apartmentFeeValueMapper.selectFeeValueVosByApartmentId(id);
        //graph_info
        List<GraphInfo> graphInfos = graphInfoMapper.selectList(Wrappers.lambdaQuery(GraphInfo.class)
                .eq(GraphInfo::getItemId, id));

        ApartmentDetailVo apartmentDetailVo = new ApartmentDetailVo();
        BeanUtils.copyProperties(apartmentInfo , apartmentDetailVo);//设置公寓数据
        apartmentDetailVo.setFacilityInfoList(facilityInfoList);
        apartmentDetailVo.setGraphVoList(graphInfos);
        apartmentDetailVo.setLabelInfoList(labelInfoList);
        apartmentDetailVo.setFeeValueVoList(feeValueVoList);
        //自定义sql查询数据组装
        // apartment_info 根据公寓id查询
        // apartment_label:
        // label_info:
        //  apartment_facility
        // facility_info:
        // apartment_fee_value:
        //  fee_value:
        //  fee_key :
        // graph_info:
        return apartmentDetailVo;
    }
}




